<?php
declare ( strict_types = 1 )
	;

namespace App\Aspect;

use Swoft\Aop\Annotation\Mapping\Aspect;
use Swoft\Aop\Annotation\Mapping\PointAnnotation;
use App\Annotation\Mapping\ActorTransaction;
use Initiating\TransactionResources\TxTransaction;
use Swoft\Aop\Annotation\Mapping\Around;
use Swoft\Aop\Point\ProceedingJoinPoint;
use Swoft\Bean\Annotation\Mapping\Inject;
use Tool\DB;
use Swoole\Coroutine;
use Initiating\AnnotationData\AnnotationData;

/**
 * 分布式事务切面
 * @Aspect(order=1)
 * @PointAnnotation(
 * include={ActorTransaction::class}
 * )
 * 
 * @author mg
 */
class ActorTransactionAspect {
	/**
	 * @Inject()
	 * 
	 * @var TxTransaction
	 */
	private $transaction;
	
	/**
	 * @Around()
	 *
	 * @param ProceedingJoinPoint $proceedingJoinPoint        	
	 *
	 * @return mixed
	 */
	public function around(ProceedingJoinPoint $proceedingJoinPoint) {
		$className = get_class ( $proceedingJoinPoint->getTarget () );
		
		$className = substr ( $className, 0, strpos ( $className, '_' ) );
		
		/**
		 *
		 * @var ActorTransaction $actorTransaction
		 */
		$actorTransaction = AnnotationData::get ( $className );
		
		if (! $actorTransaction) {
			throw new \Exception ( "没有找到切面注解对象" );
		}
		
		$this->transaction->initTrans ( DB::connection (), context ()->getRequest ()->getExt () ['x_id'] );
		
		$this->transaction->begin ();
		
		// Before around
		$result = $proceedingJoinPoint->proceed ();
		
		// After around
		
		Coroutine::create ( function (TxTransaction $trans) {
			
			Coroutine::sleep ( 6 );
			
			// 4秒之后清理链接
			if (! $trans->getTxClientManage ()->getSwooleClient ()->isConnected ()) {
				return;
			}
			vdump ( '链接关闭了' );
			$trans->getTxClientManage ()->getSwooleClient ()->close ( true );
		}, $this->transaction );
		
		if (! $result && $actorTransaction->getIsReturn ()) {
			
			$this->transaction->rollBack ();
			return $result;
		}
		
		$coroutineId = $this->transaction->commit ();
		
		return $result;
	}
}